package com.googlecode.dgwt.client.dojox.data.model;

import com.google.gwt.dom.client.Element;
import com.googlecode.dgwt.client.dijit.View;
import com.googlecode.dgwt.client.dojo.data.model.StoreColumn;
import com.googlecode.dgwt.client.dojo.data.model.StoreColumnBase;
import com.googlecode.dgwt.client.dojo.data.model.TableColumn;
import com.googlecode.dgwt.client.dojo.exception.DojoRuntimeException;
import com.googlecode.dgwt.client.dojo.exception.ValidationException;
import com.googlecode.dgwt.client.dojox.data.base.EmptyStore;
import com.googlecode.dgwt.client.dojox.data.model.base.GridColumn;
import com.googlecode.dgwt.client.dojox.data.model.base.NamedColumn;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class ProxyColumn<Item, Type> extends StoreColumnBase<Item, Type> implements GridColumn<Item, Type> {

    private StoreColumn<Item, Type> column;
    
    
    public ProxyColumn() {
        setTargetColumn(null);
    }

    public ProxyColumn(StoreColumnBase<Item, Type> targetColumn) {
        setTargetColumn(targetColumn);
    }
    
    
    @Override
    public Type onGetValue(Item item) {
        return column.getValue(item);
    }

    @Override
    public void onSetValue(Item item, Type value) {
        column.setValue(item, value);
    }

    @Override
    public void setDisplayValue(Item item, String value) throws ValidationException {
        if (column instanceof TableColumn<?,?>) {
            ((TableColumn<Item,Type>)column).setDisplayValue(item, value);
            onItemValueModified(item);
        }
    }

    @Override
    public String getDisplayValue(Item item) {
        if (column instanceof TableColumn<?,?>) {
            return ((TableColumn<Item,Type>)column).getDisplayValue(item);
        }
        Type value = getValue(item);
        return value == null ? null : value.toString();
    }

    @Override
    public int getMaxLength() {
        if (column instanceof GridColumn<?,?>) {
            return ((GridColumn<Item,Type>)column).getMaxLength();
        }
        return 0;
    }

    @Override
    public String getName() {
        if (column instanceof NamedColumn<?,?>) {
            return ((NamedColumn<Item,Type>)column).getName();
        }
        return "";
    }

    @Override
    public boolean isReadOnly() {
        return column.isReadOnly();
    }

    @Override
    public String getTitle() {
        if (column instanceof TableColumn<?,?>) {
            return ((TableColumn<Item,Type>)column).getTitle();
        }
        return getName().toUpperCase();
    }

    @Override
    public void onFormatColumn(Element element, Item item) {
        if (column instanceof TableColumn<?,?>) {
            ((TableColumn<Item,Type>)column).onFormatColumn(element, item);
        }
    }

    @Override
    public void onUpdateHeader(View parentView, Element element) {
        if (column instanceof TableColumn<?,?>) {
            ((TableColumn<Item,Type>)column).onUpdateHeader(parentView, element);
        }
    }

    @Override
    public void onFormatHeader(Element element) {
        if (column instanceof TableColumn<?,?>) {
            ((TableColumn<Item,Type>)column).onFormatHeader(element);
        }
    }

    public StoreColumnBase<Item, Type> getTargetColumn() {
        return (StoreColumnBase<Item, Type>) column;
    }

    public void setTargetColumn(StoreColumn<Item, Type> column) {
        if (column != null 
                && !(column instanceof StoreColumnBase<?,?>)){
            throw new DojoRuntimeException(this, "target column should be a StoreColumnBase descendant");
        }
        setTargetColumn((StoreColumnBase<Item, Type>) column);
    }
    
    public void setTargetColumn(StoreColumnBase<Item, Type> column) {
        if (column == null){
            column = EmptyStore.<Item,Type>getEmptyColumn();
        }
        if (column != this.column){
            if (this.column != null){
                getTargetColumn().removeProxy(this);
            }
            if (!column.addProxy(this)){
                throw new DojoRuntimeException(this, "Recusion check fail");
            }
            this.column = column;
            this.onColumnChanged();
            this.refreshValues();
        }
    }

    @Override
    public Class<? extends Type> getColumnType() {
        return column.getColumnType();
    }

    @Override
    public String getWidth() {
        if (column instanceof TableColumn<?,?>) {
            ((TableColumn<Item,Type>)column).getWidth();
        }
        return "";
    }

}
